//
// Created by DELL on 2025/2/5.
//

#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <memory>
#include <queue>
#include <vector>
#include <condition_variable>

#include "Result.h"
#include "TaskBase.h"
#include "Thread.h"

namespace zdotp {
    // 线程池模式
    enum class thread_pool_mode {
        MODE_FIXED, // 固定线程池
        MODE_CACHED // 缓存线程池
    };
    class ThreadPool {
    public:
        ThreadPool();
        ~ThreadPool();

        void set_mode(thread_pool_mode mode);
        void set_task_queue_max_threshold(unsigned int max_threshold);
        void set_thread_size_threshold(int thread_threshold);
        void start(int init_thread_num = 4);

        Result submit_task(std::shared_ptr<TaskBase> task);

        // 拷贝和赋值禁止
        ThreadPool(const ThreadPool &) = delete;
        ThreadPool &operator=(const ThreadPool &) = delete;
    private:
        thread_pool_mode mode_; // 线程池模式

        std::unordered_map<int, std::unique_ptr<Thread>> threads_; // 线程池
        int init_thread_num_; // 初始线程数
        int thread_size_threshold_; // cached模式最大线程数
        std::atomic_int current_thread_size_; // 当前线程池中的总线程 (基于cached模式)
        std::atomic_int idle_thread_size_;

        std::queue<std::shared_ptr<TaskBase>> task_queue_; // 任务队列
        std::atomic_int task_size_;
        unsigned int task_queue_max_threshold_; // 任务队列最大阈值

        std::mutex task_queue_mutex_; // 任务队列互斥锁
        std::condition_variable not_full_; // 任务队列非满条件变量
        std::condition_variable not_empty_; // 任务队列非空条件变量

        std::condition_variable exit_; // 退出线程池

        std::atomic_bool is_pool_running_;

        void thread_func(int thread_id);

        bool check_thread_running () const;

        void add_and_start();
        void remove_and_exit(int thread_id);
    };

} // zdotp

#endif //THREADPOOL_H
